#include "my_string.h"
#include <cstring>

// 无参构造
my_string::my_string(void):length(0), p_str(new char[1]{'\0'}){
}

// 有参构造
my_string::my_string(const char *p){
    length = strlen(p);
    p_str = new char[length+1];
    strcpy(p_str, p);
}

// 有参构造
my_string::my_string(int count, char value){
    length = count;
    p_str = new char[length+1];
    for(int i = 0; i < length; i++){
        p_str[i] = value;
    }
    p_str[length] = '\0';
}

// 拷贝构造
my_string::my_string(const my_string &other){
    length = other.length;
    p_str = new char[length+1];
    strcpy(p_str, other.p_str);
}

// 拷贝赋值
my_string &my_string::operator=(const my_string &other){
    if(this != &other){
        length = other.length;
        // 先释放原空间 防止内存泄露
        delete []p_str;
        // 重新分配空间
        p_str = new char[length+1];
        strcpy(p_str, other.p_str);
    }
    return *this;
}

// 拷贝赋值允许重载  目的是 用于  s = "hello"; 写法
my_string &my_string::operator=(const char *p){
    length = strlen(p);
    // 先释放原空间 防止内存泄露
    delete []p_str;
    // 重新分配空间
    p_str = new char[length+1];
    strcpy(p_str, p);
    return *this;
}

// 析构函数
my_string::~my_string(void){
    delete []p_str;
    p_str = nullptr;
}

// 获取字符串首地址
char *my_string::c_str(void)const{
    return p_str;
}

// 判断字符串是否为空
bool my_string::empty(void)const{
    return 0 == length ? true : false;
}

// 获取字符串的长度
int my_string::size(void)const{
    return length;
}

// 访问成员
char &my_string::at(int index){
    return p_str[index];
}

// 算数+ 的重载
my_string my_string::operator+(const my_string &R)const{
    my_string temp;
    temp.length = length + R.length;
    temp.p_str = new char[temp.length+1]();
    strcpy(temp.p_str, p_str);
    strcat(temp.p_str, R.p_str);
    return temp;
}

// += 运算符的重载
my_string &my_string::operator+=(const my_string &R){
    // 计算长度
    length = length + R.length;
    // 定义指针保存原来空间的地址
    char *p_temp = p_str;
    // 重新分配空间
    p_str = new char[length + 1]();
    strcpy(p_str, p_temp);
    strcat(p_str, R.p_str);
    // 释放原有的空间
    delete p_temp;
    return *this;
}

// << 运算符的重载
ostream &operator<<(ostream &x, const my_string &O){
    x << O.p_str;
    return x;
}

// >> 运算符的重载
istream &operator>>(istream &x, my_string &O){
    char temp_buff[4096];
    x >> temp_buff;
    O.length = strlen(temp_buff);
    strcpy(O.p_str, temp_buff);
    return x;
}

// << 运算符的重载
bool my_string::operator==(const my_string &R){
    return !strcmp(p_str, R.p_str) ? true : false;
}